/**
 * Notes: 支付模块控制器 - 宠物门店预约小程序
 * Date: 2025-01-27 
 */

const BaseController = require('./base_controller.js');
const PaymentService = require('../service/payment_service.js');
const UserModel = require('../model/user_model.js');
const PassportService = require('../service/passport_service.js');

class PaymentController extends BaseController {

	constructor(route, openId, event) {
		super(route, openId, event);
	}

	/**
	 * 创建支付订单
	 */
	async createPayment() {
		this.ensureAuthenticatedForWrite();
		// 数据校验
		let rules = {
			appointmentId: 'must|string|min:1|max:50|name=预约ID',
		};

		let input = this.validateData(rules);

		// 组合方案 2：下单前用户存在性校验与友好提示（必要时自动建档）
		let user = await UserModel.getOne({ _id: this._userId });
		if (!user) {
			const passport = new PassportService();
			await passport.registerUser(this._userId, {});
		}

		let service = new PaymentService();
		return await service.createPayment(input.appointmentId, this._userId);
	}

	/**
	 * 处理支付回调（微信支付 v3 + CloudPay + wxpayFunctions 兼容）
	 */
	async handlePaymentCallback() {
		// 直调兼容：前端在 TEST_MODE 下直接传入 appointmentId 和 paymentResult
		if (this._request && this._request.appointmentId) {
			let service = new PaymentService();
			const appointmentId = this._request.appointmentId;
			const paymentResult = this._request.paymentResult || {
				transactionId: this._request.transactionId,
				payTime: this._request.payTime,
				status: this._request.status || 'success'
			};
			return await service.handlePaymentCallback(appointmentId, paymentResult);
		}

		// wxpayFunctions回调处理：检查是否来自wxpayFunctions云函数
		if (this._request && this._request.action === 'payment/callback') {
			let service = new PaymentService();
			const callbackData = this._request.callbackData || {};
			
			// 根据商户订单号前缀判断订单类型
			const outTradeNo = callbackData.out_trade_no || '';
			const upper = String(outTradeNo).toUpperCase();
			
			if (upper.includes('APPOINTMENT_')) {
				// 预约订单回调
				return await service.handleWxPayFunctionsAppointmentCallback(callbackData);
			} else if (upper.includes('DEVICE_ORDER_')) {
				// 设备订单回调
				return await service.handleWxPayFunctionsDeviceCallback(callbackData);
			} else if (upper.includes('RECHARGE_')) {
				// 充值订单回调
				return await service.handleWxPayFunctionsRechargeCallback(callbackData);
			} else {
				// 默认按预约订单处理
				return await service.handleWxPayFunctionsAppointmentCallback(callbackData);
			}
		}

 		// 两种来源：
 		// 1) HTTP 触发器（微信支付 V3），从 _request 读取 headers 与 bodyRaw
 		// 2) CloudPay 回调云函数，事件直接传递字段（如 outTradeNo/returnCode 等）
 		const headers = this._request?.headers || {};
 		const bodyRaw = this._request?.bodyRaw || '';
 
 		const p = this._request || {};
 		const outTradeNo = p.outTradeNo || p.out_trade_no || '';
 		const isRefund = !!(p.refund === true || p.refund === 'true');
 		// 扩展 CloudPay 特征字段：同时包含退款通知相关字段
 		const hasCloudPayFlag = !!(outTradeNo || p.resultCode || p.returnCode || p.outRefundNo || p.out_refund_no || p.refundId);
 
 		let service = new PaymentService();
 
 		// 退款通知专用入口
 		if (isRefund) {
 			if (hasCloudPayFlag) {
 				// CloudPay 退款通知（返回纯文本）
 				return await service.cloudHandleRefundCallback(p);
 			}
 			// 微信支付 v3 退款通知
 			return await service.v3HandleRefundCallback(headers, bodyRaw);
 		}
 
 		// 如果存在 CloudPay 特征字段，按 CloudPay 直调处理并返回纯文本
 		if (hasCloudPayFlag) {
 			const upper = String(outTradeNo || '').toUpperCase();
 			if (upper.startsWith('APT')) {
 				// 预约订单 CloudPay 回调
 				return await service.cloudHandleAppointmentCallback(p);
 			}
 			if (upper.startsWith('RCH')) {
 				// 充值订单 CloudPay 回调
 				return await service.cloudHandleRechargeCallback(p);
 			}
 			if (upper.startsWith('DEV')) {
 				// 设备订单 CloudPay 回调
 				return await service.cloudHandleDeviceCallback(p);
 			}
 			// 无法识别类型：按预约订单默认处理（若缺少订单号将返回 FAIL）
 			return await service.cloudHandleAppointmentCallback(p);
 		}
 
 		// 微信支付 V3 支付回调（通用分发）
 		try {
 			// 验签
 			service._assertWechatHeaders(headers);
 			const verified = service._verifyWechatSignature(headers, bodyRaw);
 			if (!verified) {
 				return { code: 'FAIL', message: '验签失败' };
 			}
 
 			// 解密并根据订单号前缀分发
 			const notify = service._decryptWechatResource(bodyRaw);
 			const outTradeNoV3 = notify.out_trade_no || '';
 			const upperV3 = String(outTradeNoV3).toUpperCase();
 			if (upperV3.startsWith('DEV')) {
 				return await service.v3HandleDeviceCallback(headers, bodyRaw);
 			}
 			if (upperV3.startsWith('RCH')) {
 				return await service.v3HandleRechargeCallback(headers, bodyRaw);
 			}
 			// 默认按预约订单处理
 			return await service.v3HandleAppointmentCallback(headers, bodyRaw);
 		} catch (e) {
 			// 解密或验签异常时，按预约订单处理，避免推送重试风暴
 			return await service.v3HandleAppointmentCallback(headers, bodyRaw);
 		}
 	}

	/**
	 * 余额支付
	 */
	async payWithBalance() {
		this.ensureAuthenticatedForWrite();
		// 数据校验
		let rules = {
			appointmentId: 'must|string|min:1|max:50|name=预约ID',
		};

		let input = this.validateData(rules);

		// 组合方案 2：支付前用户存在性校验与友好提示（必要时自动建档）
		let user = await UserModel.getOne({ _id: this._userId });
		if (!user) {
			const passport = new PassportService();
			await passport.registerUser(this._userId, {});
		}

		let service = new PaymentService();
		return await service.payWithBalance(input.appointmentId, this._userId);
	}

	/**
	 * 申请退款
	 */
	async requestRefund() {
		this.ensureAuthenticatedForWrite();
		// 数据校验
		let rules = {
			appointmentId: 'must|string|min:1|max:50|name=预约ID',
			reason: 'string|max:200|name=退款原因',
		};

		let input = this.validateData(rules);

		// 组合方案 2：退款申请前用户存在性校验与友好提示（必要时自动建档）
		let user = await UserModel.getOne({ _id: this._userId });
		if (!user) {
			const passport = new PassportService();
			await passport.registerUser(this._userId, {});
		}

		let service = new PaymentService();
		return await service.requestRefund(input.appointmentId, this._userId, input.reason || '用户申请退款');
	}

	/**
	 * 获取交易记录
	 */
	async getTransactionRecords() {
		// 数据校验
		let rules = {
			page: 'int|min:1|default:1|name=页码',
			size: 'int|min:1|max:100|default:20|name=每页数量',
		};

		let input = this.validateData(rules);

		let service = new PaymentService();
		return await service.getTransactionRecords(this._userId, input.page, input.size);
	}

	/**
	 * 创建充值订单
	 */
	async createRechargeOrder() {
		this.ensureAuthenticatedForWrite();
		// 数据校验
		let rules = {
			amount: 'must|int|min:100|max:100000|name=充值金额', // 金额单位：分
			bonus: 'int|min:0|max:50000|default:0|name=赠送金额', // 赠送金额单位：分
			packageId: 'string|max:50|name=充值套餐ID',
		};

		let input = this.validateData(rules);

		// 组合方案 2：下单前用户存在性校验与友好提示（必要时自动建档）
		let user = await UserModel.getOne({ _id: this._userId });
		if (!user) {
			const passport = new PassportService();
			await passport.registerUser(this._userId, {});
		}

		let service = new PaymentService();
		return await service.createRechargeOrder(this._userId, input.amount, input.bonus, input.packageId);
	}

	/**
	 * 处理充值支付回调（微信支付 v3）
	 */
	async handleRechargeCallback() {
		// 直调兼容：前端在 TEST_MODE 下直接传入 rechargeOrderId 和 paymentResult
		if (this._request && this._request.rechargeOrderId) {
			let service = new PaymentService();
			const rechargeOrderId = this._request.rechargeOrderId;
			// 优先使用 paymentResult 参数
			let paymentResult = this._request.paymentResult;
			// 如果没有 paymentResult，则从其他参数中构造
			if (!paymentResult && (this._request.transactionId || this._request.payTime || this._request.status)) {
				paymentResult = {
					transactionId: this._request.transactionId || '',
					payTime: this._request.payTime || Math.floor(Date.now() / 1000),
					status: this._request.status || 'success'
				};
			}
			// 如果都没有，使用默认值
			if (!paymentResult) {
				paymentResult = {
					transactionId: '',
					payTime: Math.floor(Date.now() / 1000),
					status: 'success'
				};
			}
			console.log('[Recharge] Frontend callback invoked with:', { rechargeOrderId, paymentResult });
			return await service.handleRechargeCallback(rechargeOrderId, paymentResult);
		}
		
		// 从 HTTP 触发器透传的参数读取回调头与原始体
		const headers = this._request?.headers || {};
		const bodyRaw = this._request?.bodyRaw || '';

		let service = new PaymentService();
		const result = await service.v3HandleRechargeCallback(headers, bodyRaw);
		
		// 构造HTTP响应格式
		if (result && result.code === 'FAIL') {
			// 验签失败或其他错误
			return {
				statusCode: 400,
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ code: result.code, message: result.message })
			};
		} else {
			// 成功处理
			return {
				statusCode: 200,
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ code: 'SUCCESS', message: '处理成功' })
			};
		}
	}

	/**
	 * 处理设备订单支付回调（微信支付 v3）
	 */
	async handleDeviceCallback() {
		// 直调兼容：前端在 TEST_MODE 下直接传入设备订单号和支付结果
		if (this._request && (this._request.orderId || this._request.deviceOrderId)) {
			const orderId = this._request.orderId || this._request.deviceOrderId;
			let service = new PaymentService();
			const paymentResult = this._request.paymentResult || {
				transactionId: this._request.transactionId,
				payTime: this._request.payTime,
				status: this._request.status || 'success'
			};
			return await service.cloudHandleDeviceCallback({
				outTradeNo: orderId,
				resultCode: 'SUCCESS',
				returnCode: 'SUCCESS',
				transactionId: paymentResult.transactionId,
				payTime: paymentResult.payTime
			});
		}
		
 		// 从 HTTP 触发器透传的参数读取回调头与原始体
 		const headers = this._request?.headers || {};
 		const bodyRaw = this._request?.bodyRaw || '';
 
 		let service = new PaymentService();
 		return await service.v3HandleDeviceCallback(headers, bodyRaw);
 	}



	/**
	 * 获取用户充值记录
	 */
	async getRechargeRecords() {
		// 数据校验
		let rules = {
			page: 'int|min:1|default:1|name=页码',
			size: 'int|min:1|max:100|default:20|name=每页数量',
		};

		let input = this.validateData(rules);

		let service = new PaymentService();
		return await service.getUserRechargeRecords(this._userId, input.page, input.size);
	}

	/**
	 * 查询微信支付订单（通过商户订单号）
	 */
	async queryByOutTradeNo() {
		// GET 兼容：支持匿名用户读取
		let rules = {
			out_trade_no: 'must|string|min:1|max:64|name=商户订单号'
		};
		let input = this.validateData(rules);
		let service = new PaymentService();
		return await service.queryOrderByOutTradeNo(input.out_trade_no);
	}

	/**
	 * 查询微信支付订单（通过微信订单号）
	 */
	async queryByTransactionId() {
		let rules = {
			transaction_id: 'must|string|min:1|max:64|name=微信订单号'
		};
		let input = this.validateData(rules);
		let service = new PaymentService();
		return await service.queryOrderByTransactionId(input.transaction_id);
	}

	/**
	 * 申请微信支付退款（兼容 /api/payment/refund）
	 */
	async refund() {
		this.ensureAuthenticatedForWrite();
		let rules = {
			out_trade_no: 'must|string|min:1|max:64|name=商户订单号',
			out_refund_no: 'must|string|min:1|max:64|name=商户退款单号',
			total: 'must|int|min:1|max:100000000|name=原订单金额（分）',
			refund: 'must|int|min:1|max:100000000|name=退款金额（分）',
			reason: 'string|max:200|name=退款原因'
		};
		let input = this.validateData(rules);
		let service = new PaymentService();
		return await service.createWxPayRefund(input);
	}
}

module.exports = PaymentController;
